﻿using ER.Dynamic;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Configuration;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.Compilation;

namespace ER.Tests.Data
{
    public class DummyDbContextBuilder : IDbContextBuilder
    {
        string NameSpace = "ER.Tests.DynamicWebApp.Data";
        public void Build()
        {
            TypeEmiter typeEmployeeEmiter = Emiter.CreateTypeEmiter(NameSpace + ".Employee");
            typeEmployeeEmiter.AddPropertyEmiter("EmployeeId", typeof(int));
            PropertyEmiter emNameProp = typeEmployeeEmiter.AddPropertyEmiter("Name", typeof(String));
            //emNameProp.AddCustomAttribute(typeof(System.ComponentModel.DataAnnotations.DisplayAttribute), new String[]{"Name"}, new []{"Employee Display Name"});
            emNameProp.AddDisplayAttribute("Employee Display Name 2");
            PropertyEmiter ageProp = typeEmployeeEmiter.AddPropertyEmiter("Age", typeof(int));
            typeEmployeeEmiter.Emit();

            TypeEmiter typeClassEmiter = Emiter.CreateTypeEmiter(NameSpace + ".Class");
            typeClassEmiter.AddPropertyEmiter("ClassId", typeof(int));
            typeClassEmiter.AddPropertyEmiter("ClassName", typeof(String));
            typeClassEmiter.Emit();

            TypeEmiter typeStudentEmiter = Emiter.CreateTypeEmiter(NameSpace + ".Student");
            typeStudentEmiter.AddPropertyEmiter("StudentId", typeof(int));
            typeStudentEmiter.AddPropertyEmiter("Name", typeof(String));
            typeStudentEmiter.AddPropertyEmiter("Class", typeClassEmiter);
            typeStudentEmiter.AddPropertyEmiter("ClassId", typeof(int));
            typeStudentEmiter.Emit();

            TypeDbContextEmiter = Emiter.CreateTypeEmiter(NameSpace + ".RuntimeDbContext");
            TypeDbContextEmiter.BaseType = typeof(DbContext);
            TypeDbContextEmiter.AddConstructorEmiter(new[] { typeof(string) });
            var stDbSet = typeof(DbSet<>).MakeGenericType(typeStudentEmiter);
            var emDbSet = typeof(DbSet<>).MakeGenericType(typeEmployeeEmiter);
            var classDbSet = typeof(DbSet<>).MakeGenericType(typeClassEmiter);
            TypeDbContextEmiter.AddPropertyEmiter("Students", stDbSet);
            TypeDbContextEmiter.AddPropertyEmiter("Employees", emDbSet);
            TypeDbContextEmiter.AddPropertyEmiter("Classes", classDbSet);
            TypeDbContextEmiter.Emit();
            
        }

        public TypeEmiter TypeDbContextEmiter{get; private set;}

        public DbContext CreateDbContext(string connectString)
        {
            return TypeDbContextEmiter.CreateObject(connectString) as DbContext;
        }
    }
}
